package com.ruicar.afs.cloud.admin.component;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONObject;
import com.ruicar.afs.cloud.admin.dto.SysApiAllowIp;
import com.ruicar.afs.cloud.admin.dto.SysApiControl;
import com.ruicar.afs.cloud.admin.mapper.SysApiControlMapper;
import com.ruicar.afs.cloud.apicontrol.constant.Constants;
import com.ruicar.afs.cloud.apicontrol.dto.ApiConfigBean;
import com.ruicar.afs.cloud.common.core.constant.CommonConstants;
import com.ruicar.afs.cloud.common.core.util.AfsApiControlUtil;
import com.ruicar.afs.cloud.common.datasync.componts.SyncHelper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

@Component
@AllArgsConstructor
@Slf4j
public class ApiControlDispatcher implements ApplicationListener<ApplicationReadyEvent> {
    private final SysApiControlMapper sysApiControlMapper;
    private static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE = Executors.newScheduledThreadPool(1);
    private static  String LAST_MD5 = "";
    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        SCHEDULED_EXECUTOR_SERVICE.scheduleWithFixedDelay(this::publishApiControl,2,60, TimeUnit.SECONDS);
    }
    private void publishApiControl(){
        try {
            ApiConfigBean apiConfigBean = new ApiConfigBean();
            List<SysApiControl> list= sysApiControlMapper.queryApis();
            Map<String,List<SysApiControl>> listMap = list.stream()
                    .collect(Collectors.groupingBy(SysApiControl::getServiceName));
            Map<String, Map<String, AfsApiControlUtil.ApiControlConfig>> data = new HashMap<>();
            listMap.entrySet().stream().forEach(entry->{
                Map<String, AfsApiControlUtil.ApiControlConfig> map=  entry.getValue().stream().map(sysApiControl -> {
                    AfsApiControlUtil.ApiControlConfig apiControlConfig = new AfsApiControlUtil.ApiControlConfig();
                    apiControlConfig.setLevel(sysApiControl.getMatchLevel());
                    apiControlConfig.setUri(sysApiControl.getApiUri());
                    apiControlConfig.setAllowRules(sysApiControl.getApiAllowIps().stream().map(SysApiAllowIp::getIpPattern).collect(Collectors.toSet()));
                    return apiControlConfig;
                }).collect(Collectors.toMap(AfsApiControlUtil.ApiControlConfig::getUri, Function.identity()));
                data.put(entry.getKey(),map);
            });
            if(CollectionUtil.isNotEmpty(data)){
                apiConfigBean.setData(data);
            }else{
                data.put(CommonConstants._BASE_DS_NAME,new HashMap<>());
                apiConfigBean.setData(data);
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(Constants.KEY.getKey(),apiConfigBean);
            String md5 = SecureUtil.md5(jsonObject.toJSONString());
            if(!StringUtils.equals(SecureUtil.md5(jsonObject.toJSONString()),LAST_MD5)){
                SyncHelper.publishParams(Constants.KEY,jsonObject);
                LAST_MD5 = md5;
            }
        }catch (Exception e){
            log.error("",e);
        }
    }
}
